<?php

namespace Jylnnlee\HyperfGenFullstack\Generator;

use InvalidArgumentException;
use Util\HyperfGenFullstack\Helper\TypeMapper;

class MigrationGenerator
{
    public static function generate(string $table, array $columns, bool $softDelete = true): void
    {
        // 校验表名合法性
        if (!preg_match('/^[a-z0-9_]+$/', $table)) {
            throw new InvalidArgumentException("Invalid table name: $table");
        }

        $migrationName = self::formatMigrationName($table);
        $dir = "databases/migrations/";

        // 确保目录存在
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }

        $upBody = '';
        foreach ($columns as $column) {
            $line = self::buildColumnLine($column);
            $upBody .= "            $line\n";
        }

        if ($softDelete) {
            $upBody .= "            \$table->dateTime('deleted_at')->nullable(); // 软删除字段\n";
        }

        $template = <<<PHP
<?php

declare(strict_types=1);

use Hyperf\\Database\\Schema\\Schema;
use Hyperf\\Database\\Migrations\\Migration;
use Hyperf\\Database\\Schema\\Blueprint;

class Create%sTable extends Migration
{
    public function up(): void
    {
        Schema::create('%s', function (Blueprint \$table) {
%s        });
    }

    public function down(): void
    {
        Schema::dropIfExists('%s');
    }
}
PHP;

        $content = sprintf($template, ucfirst($table), $table, $upBody, $table);
        file_put_contents("$dir$migrationName", $content);
    }

    private static function buildColumnLine(array $column): string
    {
        $name = $column['name'];
        $type = $column['type'] ?? 'string';

        // 校验字段名合法性
        if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $name)) {
            throw new InvalidArgumentException("Invalid column name: $name");
        }

        $default = $column['default'] ?? null;
        $nullable = $column['nullable'] ? '->nullable()' : '';
        $comment = $column['comment'] ? "->comment('" . str_replace("'", "\'", $column['comment']) . "')" : '';

        // 使用 TypeMapper 映射类型
        $typeMethod = TypeMapper::mapToSchemaMethod($type);
        $length = $column['length'] ?? 255;

        $line = match ($typeMethod) {
            'string' => "\$table->string('$name', $length)",
            'integer' => "\$table->integer('$name')",
            'bigInteger' => "\$table->bigInteger('$name')",
            'text' => "\$table->text('$name')",
            'dateTime' => "\$table->dateTime('$name')",
            'json' => "\$table->json('$name')",
            default => "\$table->$typeMethod('$name')",
        };

        if ($default !== null) {
            if (is_bool($default)) {
                $defaultExpr = $default ? 'true' : 'false';
            } elseif (is_string($default) && preg_match('/^\w+\(.*\)$/', $default)) {
                // 支持 raw 表达式，如 CURRENT_TIMESTAMP
                $line .= "->default($default)";
                return $line . $nullable . $comment . ';';
            } else {
                $defaultExpr = is_string($default) ? "'$default'" : $default;
            }
            $line .= "->default($defaultExpr)";
        }

        $line .= $nullable . $comment . ';';

        return $line;
    }

    private static function formatMigrationName(string $table): string
    {
        return date('Y_m_d_His') . "_create_{$table}_table.php";
    }
}
